/* 
 * File:   ipd_scaling.cpp
 * Author: dima
 * 
 * Created on 22 февраля 2015 г., 15:49
 */

#include "ipd_scaling.h"
#include <math.h>
namespace ipd
{

ipd_scaling::ipd_scaling(ipd_img &orig_img) : orig_image(orig_img)
{
}

ipd_scaling::ipd_scaling(const ipd_scaling& orig) : orig_image(orig.orig_image)
{
}

ipd_scaling::~ipd_scaling()
{
}
void ipd_scaling::bilinear_interpolation(ipd_img &img,float scale)
{
    int h, w;
    float t;
    float u;
    float tmp;
    float d1, d2, d3, d4;
    unsigned char *p1, *p2, *p3, *p4; /* Окрестные пикселы */
    unsigned char r[3];

    color_model type_img=orig_image.get_color_type();
    int height = orig_image.get_height();
    int width = orig_image.get_width();
    int h_img = height*scale;
    int w_img = width*scale;
    img.init(w_img, h_img,type_img);
    
    for (int j = 0; j < h_img; j++) 
    {
        tmp = (float) (j) / (float) (h_img - 1) * (height - 1);
        h = (int) floor(tmp);
        if (h < 0)
        {
            h = 0;
        }
        else
        {
            if (h >= height - 1)
                h = height - 2;
        }
        u = tmp - h;
        for (int i = 0; i < w_img; i++)
        {

            tmp = (float) (i) / (float) (w_img - 1) * (width - 1);
            w = (int) floor(tmp);
            if (w < 0)
            {
                w = 0;
            }
            else
            {
                if (w >= width - 1)
                    w = width - 2;
            }
            t = tmp - w;

            /* Коэффициенты */
            d1 = (1 - t) * (1 - u);
            d2 = t * (1 - u);
            d3 = t * u;
            d4 = (1 - t) * u;

            /* Окрестные пиксели: a[i][j] */
            p1 = orig_image.get_color(w, h);
            p2 = orig_image.get_color(w + 1, h);
            p3 = orig_image.get_color(w + 1, h + 1);
            p4 = orig_image.get_color(w, h + 1);


            switch (type_img)
            {
            case tp_RGB:
            {
                for (int k = 0; k < sz_RGB; k++)
                    r[k] = p1[k] * d1 + p2[k] * d2 + p3[k] * d3 + p4[k] * d4;
                break;
            }
            case tp_mono:
            {
                r[0] = p1[0] * d1 + p2[0] * d2 + p3[0] * d3 + p4[0] * d4;
                break;
            }
            }
            img.set_color(i, j, r);
        }
    }

}
void ipd_scaling::duplicating_pixels(ipd_img &img, int scale, bool increase)
{
    if (increase)
        increase_img(img, scale);
    else
        decrease_img(img, scale);

}

void ipd_scaling::decrease_img(ipd_img &img, int scale)
{
    unsigned char* ch;
    int i, j;
    int w_img = orig_image.get_width() / scale;
    int h_img = orig_image.get_height() / scale;
    img.init(w_img, h_img, orig_image.get_color_type());
    for (i = 0; i < w_img; i++)
        for (j = 0; j < h_img; j++)
        {
            ch = orig_image.get_color(i * scale, j * scale);
            img.set_color(i, j, ch);
        }
}

void ipd_scaling::increase_img(ipd_img &img, int scale)
{
    unsigned char* ch;
    int i, j;
    int width = orig_image.get_width();
    int height = orig_image.get_height();

    int w_img = width * scale;
    int h_img = height * scale;
    img.init(w_img, h_img, orig_image.get_color_type());

    for (j = 0; j < h_img; j++)
        for (i = 0; i < w_img; i++)
        {
            ch = orig_image.get_color(i / (double) scale, j / (double) scale);
            img.set_color(i, j, ch);
        }
}

}